package GA_Test;
import 多无人机架次.TimeCount;
import java.util.*;

public class Operators_Off_Down {
    static SpeciesPopulation off_down(SpeciesPopulation new_list, float now_tem) {
        SpeciesPopulation new_pop = new SpeciesPopulation();
        big:
        for (int i = 0; i < new_list.specPopu.size(); i++) {//拿出一个个体
            SpeciesIndividual now_individual = new_list.specPopu.get(i);
            for(int k = 0;k<now_individual.TruckGenes.size();k++){ //也别随机选了  就是把每一个车辆路径下的最优找出来
                ArrayList<Integer> truck_route =  (ArrayList<Integer>) now_individual.TruckGenes.get(k);
                ArrayList<Integer> drone_route = (ArrayList<Integer>) now_individual.DroneGenes.get(k);
                if (drone_route.size() != 0) { //不等于0 说明 当前选的这车上面有无人机架次
                    change(truck_route, drone_route); //调用这个方法实现对指定 无人机的路径更改
                    break;
                } else { //如果当前车辆上没有无人机架次的话  就继续找另一辆车
                    continue big;
                }
            }
            now_individual.calFitness();
            new_pop.add(now_individual.clone());
        }
        return new_pop;
    }

    //下面方法用于交换某条车辆和对应无人机的起飞点与降落点   返回的是无人机路径
    private static void change(ArrayList<Integer> truck_route, ArrayList<Integer> drone_route) {

        double best = TimeCount.timeCount(truck_route,drone_route);//将当前传进来的这个组合的时间设为最好的
        ArrayList<Integer> message = new ArrayList<>();
        for (int t = 0; t < truck_route.size(); t++) {
            for (int d = 0; d < drone_route.size(); d++) {
                if (truck_route.get(t) == drone_route.get(d)) {
                    message.add(t);
                    message.add(d);
                    message.add(truck_route.get(t));
                }
            }
        }
        if(message.size()<6){
            return;
        }
        int truck_off1_position = message.get(0); //车辆访问路径中 无人机第一次起飞的位置
        int drone_off1_position = message.get(1);// 无人机路径中  无人机第一次起飞的位置
        int off1 = message.get(2);// 起飞的客户点
        int truck_down1_position = message.get(3);//车辆访问路径中 无人机第一次降落的位置
        int drone_down1_position = message.get(4);//无人机路径中 无人机第一次降落的位置
        int down1 = message.get(5);//降落的客户点
        int truck_off2_position = 0;
        int drone_off2_position = 0;
        int off2 = 0;
        int truck_down2_position = 0;
        int drone_down2_position = 0;
        int down2 = 0;
        if (message.size() > 6) {
            truck_off2_position = message.get(6);
            drone_off2_position = message.get(7);
            off2 = message.get(8);
//            System.out.println(truck_route);
//            System.out.println(drone_route);
//            System.out.println(message);
            truck_down2_position = message.get(9);
            drone_down2_position = message.get(10);
            down2 = message.get(11);
        }
        if (message.size() == 6) {//只有一个架次  单架次用随机撞
          while(true) {
              Random r = new Random();
              int off = r.nextInt(truck_route.size() - 1);
              int down = r.nextInt(truck_route.size() );
              if(down>off){
                  drone_route.set(0,truck_route.get(off));
                  drone_route.set(drone_route.size()-1,truck_route.get(down));
                  break;
              }else{
                  continue;
              }
          }
        } else { //有两个架次
            if (truck_down1_position - truck_off1_position > 1) {//更换无人机第一架次的起飞点
                //把无人机第一架次的起飞点替换成车辆后面一个点
                ArrayList<Integer> arr1 = new ArrayList<>();
                for (int i = 0; i < drone_route.size(); i++) {
                    arr1.add(drone_route.get(i));//把当前的无人机路径 给存起来
                }//把无人机路径赋给 arr1
                drone_route.set(drone_off1_position, truck_route.get(truck_off1_position + 1)); //更改无人机路径
                double time = TimeCount.timeCount(truck_route, drone_route);//计算更改后的运行时间
                if (time < best) {
                    best = time;//如何时间比总时间好  那就保存这个最好时间  保存这个无人机路径
                } else { //如果更改后的时间还没有原来的路径好  那就把更改后的无人机路径还原
                    for (int k = 0; k < arr1.size(); k++) {
                        drone_route.set(k, arr1.get(k));
                    }
                }
            }
            if (truck_off2_position - truck_down1_position > 1) {
                //把第一架次无人机降落点往后挪一位
                ArrayList<Integer> arr2 = new ArrayList<>();
                for (int i = 0; i < drone_route.size(); i++) {
                    arr2.add(drone_route.get(i));//把当前的无人机路径 给存起来
                }//把无人机路径赋给 arr2
                drone_route.set(drone_down1_position, truck_route.get(truck_down1_position + 1)); //更改无人机路径
                double time = TimeCount.timeCount(truck_route, drone_route);//计算更改后的运行时间
                if (time < best) {
                    best = time;//如何时间比总时间好  那就保存这个最好时间  保存这个无人机路径
                } else { //如果更改后的时间还没有原来的路径好  那就把更改后的无人机路径还原
                    for (int k = 0; k < arr2.size(); k++) {
                        drone_route.set(k, arr2.get(k));
                    }
                }
            }
            if (truck_down2_position - truck_off2_position > 1) {
                //把第二架次无人机的起飞点往后挪一位
                ArrayList<Integer> arr = new ArrayList<>();
                for (int i = 0; i < drone_route.size(); i++) {
                    arr.add(drone_route.get(i));//把当前的无人机路径 给存起来
                }//把无人机路径赋给 arr2
                drone_route.set(drone_off2_position, truck_route.get(truck_off2_position + 1)); //交换过程
                double time = TimeCount.timeCount(truck_route, drone_route);//计算更改后的运行时间
                if (time < best) {
                    best = time;//如何时间比总时间好  那就保存这个最好时间  保存这个无人机路径
                } else { //如果更改后的时间还没有原来的路径好  那就把更改后的无人机路径还原
                    for (int k = 0; k < arr.size(); k++) {
                        drone_route.set(k, arr.get(k));
                    }
                }
            }
            if (truck_down2_position != truck_route.size() - 1) {
                //把第二架次无人机的降落点往后挪一位
                ArrayList<Integer> arr = new ArrayList<>();
                for (int i = 0; i < drone_route.size(); i++) {
                    arr.add(drone_route.get(i));//把当前的无人机路径 给存起来
                }//把无人机路径赋给 arr2
                drone_route.set(drone_down2_position, truck_route.get(truck_down2_position + 1)); //交换过程
                double time = TimeCount.timeCount(truck_route, drone_route);//计算更改后的运行时间
                //这里加一个约束判断的语句 用来对交换后的 结果进行约束检查
                if(isok(truck_route,drone_route)==true){
                    if (time < best) {
                        best = time;//如何时间比总时间好  那就保存这个最好时间  保存这个无人机路径
                    } else { //如果更改后的时间还没有原来的路径好  那就把更改后的无人机路径还原
                        for (int k = 0; k < arr.size(); k++) {
                            drone_route.set(k, arr.get(k));
                        }
                    }
                }else {
                    for (int k = 0; k < arr.size(); k++) {
                        drone_route.set(k, arr.get(k));
                    }
                }

            }
        }

    }
    private static boolean isok(ArrayList<Integer> truck, ArrayList<Integer> drone) {
        boolean flag = true;

        ArrayList<Integer> message = new ArrayList<>();
        for (int t = 0; t < truck.size(); t++) {
            for (int d = 0; d < drone.size(); d++) {
                if (truck.get(t) == drone.get(d)) {
                    message.add(t);
                    message.add(d);
                    message.add(truck.get(t));
                }
            }
        }
        int truck_off1_position = message.get(0); //车辆访问路径中 无人机第一次起飞的位置
        int drone_off1_position = message.get(1);// 无人机路径中  无人机第一次起飞的位置
        int off1 = message.get(2);// 起飞的客户点

        int truck_down1_position = message.get(3);//车辆访问路径中 无人机第一次降落的位置
        int drone_down1_position = message.get(4);//无人机路径中 无人机第一次降落的位置
        int down1 = message.get(5);//降落的客户点
        int truck_off2_position = 0;
        int drone_off2_position = 0;
        int off2 = 0;
        int truck_down2_position = 0;
        int drone_down2_position = 0;
        int down2 = 0;
        if (message.size() > 6) {
            truck_off2_position = message.get(6);
            drone_off2_position = message.get(7);
            off2 = message.get(8);
            truck_down2_position = message.get(9);
            drone_down2_position = message.get(10);
            down2 = message.get(11);
        }
        double drone_distance1 =0; int cap1 = 0;
        double drone_distance2 =0; int cap2 = 0;
        for(int k =drone_off1_position;k<drone_down1_position;k++){
            drone_distance1 += GAData.disCollection[drone.get(k)][drone.get(k+1)]; //无人机第一架次距离计算
        }
        for(int k = drone_off1_position+1;k<drone_down1_position;k++){//无人机第一架次载重计算
            cap1 += GAData.cusInfo[k].demand;
        }
        if(drone_distance1> GAData.distanceDrone || cap1>GAData.capacityDrone){
            flag = false;
        }
        if(drone_off2_position!=0){
            for(int k =drone_off2_position;k<drone_down2_position;k++){
                drone_distance2 += GAData.disCollection[drone.get(k)][drone.get(k+1)]; //无人机第一架次距离计算
            }
            for(int k = drone_off2_position+1;k<drone_down2_position;k++){//无人机第二架次载重计算
                cap2 += GAData.cusInfo[k].demand;
            }
        }
        if(drone_distance2>GAData.distanceDrone || cap2> GAData.capacityDrone){
            flag = false;
        }
        return flag;
    }
}